package org.ns.framework.datasource.mybatis;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

public class MapperProxy implements InvocationHandler {
    SqlSessionFactory sqlSessionFactory;
    String dataSourceName;
    MybatisMapperManage mybatisMapperManage;

    Class<?> mapperType;
    boolean transactionAutoCommit = false;

    public MapperProxy(SqlSessionFactory sqlSessionFactory, String dataSourceName, MybatisMapperManage mybatisMapperManage, Class<?> mapperType) {
        this.sqlSessionFactory = sqlSessionFactory;
        this.dataSourceName = dataSourceName;
        this.mybatisMapperManage = mybatisMapperManage;
        this.mapperType = mapperType;
        this.transactionAutoCommit = mybatisMapperManage.isAutoCommit(dataSourceName);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        MybatisTransactionReference transactonManage = (MybatisTransactionReference)TransactionManage.get();
        SqlSession sqlSession = null;

        try {
        	boolean autoCommit = false;
            if (transactonManage != null) {
            	transactonManage.setDefaultAutoCommit(transactionAutoCommit); // 配置默认时是否自动提交.
                sqlSession = transactonManage.openSession(dataSourceName, sqlSessionFactory);
                autoCommit = false;
            } else {
                sqlSession = sqlSessionFactory.openSession(true);
                autoCommit = true;
            }

            Object mapper = sqlSession.getMapper(mapperType);
            Object result =  method.invoke(mapper, args);
            if (autoCommit) {
            	sqlSession.commit(true);
            }
            return result;
        } catch (Throwable e) {
            throw e;
        } finally {
            if (transactonManage == null && sqlSession != null) {
                sqlSession.close();
            }
        }
    }
}
